package com.hdax.dm.Service;

import com.hdax.dm.dto.item.Item;
import com.hdax.dm.dto.item.ItemDto;
import com.hdax.dm.entity.base.Image;
import com.hdax.dm.feign.base.ImageFeign;
import com.hdax.dm.vo.EsItem;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class BaseService {

    @Autowired
    private ElasticsearchRestTemplate esTemplate;
    @Autowired
    private ImageFeign imageFeign;

    public ItemDto query(Map<String,Object> map){

        ItemDto itemDto = new ItemDto();
        List<Item> rows = new ArrayList<>();

        Integer currentPage = (Integer) map.get("currentPage");
        Integer pageSize = (Integer) map.get("pageSize");
        Integer areaId = (Integer) map.get("areaId");
        String keyword = "";
        if (map.size() > 8){
            if (!map.get("keyword").equals("") && map.get("keyword") != null){
                keyword = map.get("keyword").toString();
            }
        }
        Integer itemType1Id = (Integer) map.get("itemTypeId1");
        Integer itemType2Id = (Integer) map.get("itemTypeId2");

        String startTime = map.get("startTime").toString();
        String endTime = map.get("endTime").toString();

        //构建查询对象
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if(!keyword.trim().equals("")){
            queryBuilder.should(QueryBuilders.matchQuery("abstractmessage",keyword));
            queryBuilder.must(QueryBuilders.matchQuery("itemname",keyword));
        }

        if (areaId != 0){
            queryBuilder.must(QueryBuilders.termQuery("areaid",areaId));
        }

        if (itemType1Id != 0){
            queryBuilder.must(QueryBuilders.termQuery("itemtype1id",itemType1Id));
        }
        if (itemType2Id != 0){
            queryBuilder.must(QueryBuilders.termQuery("itemtype2id",itemType2Id));
        }

        if (!startTime.trim().equals("") && !endTime.trim().equals("")){
            //时间转换
            LocalDate startDate = LocalDate.parse(startTime);
            LocalDate endDate = LocalDate.parse(endTime);
            //范围查询
            queryBuilder.must(QueryBuilders.rangeQuery("starttime").gte(startDate).lte(endDate));
        }

        //接受排序规则
        String sort = map.get("sort").toString();
        //排序对象
        SortBuilder sortBuilder = null;
        boolean isSort = false;
        if (sort.equals("recommend")){
            queryBuilder.must(QueryBuilders.termQuery("isrecommend",1));
        } else if (sort.equals("recentShow")){
            isSort = true;
            queryBuilder.must(QueryBuilders.rangeQuery("starttime").gte(LocalDate.now()).lte(LocalDate.now()));
            //排序
            sortBuilder = SortBuilders.fieldSort("starttime").order(SortOrder.DESC);
        } else if (sort.equals("recentSell")) {
            isSort = true;
            sortBuilder = SortBuilders.fieldSort("createdtime").order(SortOrder.DESC);
        }
        //封装组合查询条件
        NativeSearchQuery nativeSearchQuery = null;
        if (isSort){
            nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder).withHighlightFields(
                    new HighlightBuilder.Field("itemname"),
                    new HighlightBuilder.Field("abstractmessage")
            ).withHighlightBuilder(new HighlightBuilder().preTags("<span style = 'color:red'>").postTags("</span>"))
                    //分页
                    .withPageable(PageRequest.of(currentPage-1,pageSize))
                    //排序                  收尾
                    .withSort(sortBuilder).build();
        } else {
            nativeSearchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder).withHighlightFields(
                    new HighlightBuilder.Field("itemname"),
                    new HighlightBuilder.Field("abstractmessage")
            ).withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>"))
                    //分页
                    .withPageable(PageRequest.of(currentPage-1,pageSize)).build();
        }

        //执行查询
        SearchHits<EsItem> searchHits = esTemplate.search(nativeSearchQuery,EsItem.class);
        //封装查询结果
        List<EsItem> list = new ArrayList<>();
        //转换
        searchHits.getSearchHits().forEach(searchHit->{
            Map<String,List<String>> higelightFields = searchHit.getHighlightFields();
            Item item = new Item();
            EsItem esItem = searchHit.getContent();
            BeanUtils.copyProperties(esItem,item);
            Image image = imageFeign.image(esItem.getId(), 2L, 1L);
            item.setImgUrl(image == null?"":image.getImgUrl());
            //处理高亮
            item.setItemName(higelightFields.get("itemname") == null ?
                    searchHit.getContent().getItemName():
                    higelightFields.get("itemname").get(0));
            item.setAbstractMessage(higelightFields.get("abstractmessage") == null ?
                    searchHit.getContent().getAbstractMessage():
                    higelightFields.get("abstractmessage").get(0));
            item.setAdress(esItem.getAddress());
            rows.add(item);
        });
        itemDto.setCurrentPage(Long.valueOf(currentPage));
        itemDto.setPageSize(Long.valueOf(pageSize));
        itemDto.setRows(rows);
        return itemDto;
    }

}
